from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
from datetime import datetime, timedelta
from .dingtalk_api import DingTalkAPI
import logging

_logger = logging.getLogger(__name__)


class DingTalkConfig(models.Model):
    _name = 'dingtalk.config'
    _description = '钉钉配置'
    _rec_name = 'name'
    
    name = fields.Char(string="配置名称", required=True, default="钉钉配置")
    
    # 应用配置
    app_key = fields.Char(string="AppKey", required=True, help="钉钉应用的 AppKey")
    app_secret = fields.Char(string="AppSecret", required=True, groups="base.group_system", 
                            help="钉钉应用的 AppSecret（敏感信息）")
    agent_id = fields.Char(string="AgentID", help="应用的 AgentID，用于发送工作通知")
    
    # 回调地址配置
    callback_domain = fields.Char(string="回调域名", default="https://naturedao.tech",
                                 help="钉钉登录回调地址的域名，例如: https://naturedao.tech")
    
    # Token 信息
    access_token = fields.Char(string="Access Token", readonly=True, 
                               help="当前有效的 Access Token")
    token_expire_time = fields.Datetime(string="Token 过期时间", readonly=True,
                                       help="Access Token 的过期时间")
    token_status = fields.Selection([
        ('valid', '有效'),
        ('expired', '已过期'),
        ('not_obtained', '未获取'),
    ], string="Token 状态", compute='_compute_token_status', store=True)
    
    # 机器人配置
    robot_type = fields.Selection([
        ('webhook', '自定义机器人（Webhook）'),
        ('org', '企业内部机器人'),
    ], string="机器人类型", default='org', help="选择使用的机器人类型")
    
    # 自定义机器人配置（用于群聊）
    robot_webhook = fields.Char(string="Webhook URL", 
                                help="自定义机器人的 Webhook URL")
    robot_secret = fields.Char(string="Webhook 密钥", groups="base.group_system",
                              help="自定义机器人的加签密钥")
    
    # 企业内部机器人配置
    robot_code = fields.Char(string="机器人 Code", 
                            help="企业内部机器人的唯一标识码（RobotCode）")
    
    # 统计信息
    last_sync_time = fields.Datetime(string="最后同步时间", readonly=True)
    total_departments = fields.Integer(string="部门总数", readonly=True)
    total_employees = fields.Integer(string="员工总数", readonly=True)
    
    # 配置状态
    active = fields.Boolean(string="启用", default=True)
    
    @api.depends('access_token', 'token_expire_time')
    def _compute_token_status(self):
        """计算 Token 状态"""
        for record in self:
            if not record.access_token:
                record.token_status = 'not_obtained'
            elif not record.token_expire_time:
                record.token_status = 'not_obtained'
            elif fields.Datetime.now() >= record.token_expire_time:
                record.token_status = 'expired'
            else:
                record.token_status = 'valid'
    
    def _get_api_client(self):
        """获取 API 客户端"""
        self.ensure_one()
        return DingTalkAPI(self.app_key, self.app_secret, self.agent_id)
    
    def get_valid_access_token(self):
        """获取有效的 Access Token（自动刷新）"""
        self.ensure_one()
        
        # 检查是否需要刷新
        if self.token_status == 'valid' and self.access_token:
            return self.access_token
        
        # 获取新 Token
        api = self._get_api_client()
        token = api.get_access_token()
        
        if token:
            self.sudo().write({
                'access_token': token,
                'token_expire_time': fields.Datetime.now() + timedelta(seconds=7200-300),  # 提前 5 分钟过期
            })
            return token
        else:
            raise ValidationError(_('无法获取 Access Token，请检查 AppKey 和 AppSecret 是否正确'))
    
    def action_test_connection(self):
        """测试连接"""
        self.ensure_one()
        
        try:
            # 尝试获取 Token
            token = self.get_valid_access_token()
            
            if token:
                # 尝试获取根部门信息
                api = self._get_api_client()
                dept_list = api.get_department_list(token, 1)
                
                return {
                    'type': 'ir.actions.client',
                    'tag': 'display_notification',
                    'params': {
                        'title': _('连接成功'),
                        'message': _('成功连接到钉钉！找到 %d 个顶级部门。') % len(dept_list),
                        'type': 'success',
                        'sticky': False,
                    }
                }
            else:
                raise ValidationError(_('连接失败'))
                
        except Exception as e:
            return {
                'type': 'ir.actions.client',
                'tag': 'display_notification',
                'params': {
                    'title': _('连接失败'),
                    'message': _('错误: %s') % str(e),
                    'type': 'danger',
                    'sticky': True,
                }
            }
    
    def action_refresh_token(self):
        """手动强制刷新 Token"""
        self.ensure_one()
        
        try:
            import logging
            _logger = logging.getLogger(__name__)
            
            # 强制获取新 Token（不检查当前状态）
            api = self._get_api_client()
            token = api.get_access_token()
            
            if token:
                expire_time = fields.Datetime.now() + timedelta(seconds=7200-300)  # 提前 5 分钟过期
                self.sudo().write({
                    'access_token': token,
                    'token_expire_time': expire_time,
                })
                
                _logger.info(f"✅ Token 刷新成功")
                _logger.info(f"   新 Token: {token[:20]}...")
                _logger.info(f"   过期时间: {expire_time}")
                
                return {
                    'type': 'ir.actions.client',
                    'tag': 'display_notification',
                    'params': {
                        'title': _('✅ 刷新成功'),
                        'message': _('Access Token 已刷新\n过期时间: %s') % expire_time.strftime('%Y-%m-%d %H:%M:%S'),
                        'type': 'success',
                        'sticky': False,
                        'next': {'type': 'ir.actions.act_window', 'res_model': 'dingtalk.config', 'res_id': self.id, 'views': [[False, 'form']], 'target': 'current'},
                    }
                }
            else:
                raise ValidationError(_('无法获取 Access Token，请检查 AppKey 和 AppSecret'))
                
        except Exception as e:
            import logging
            _logger = logging.getLogger(__name__)
            _logger.error(f"❌ Token 刷新失败: {str(e)}")
            raise ValidationError(_('刷新 Token 失败: %s') % str(e))
    
    @api.model
    def get_default_config(self):
        """获取默认配置（第一个启用的配置）"""
        config = self.search([('active', '=', True)], limit=1)
        if not config:
            raise ValidationError(_('未找到钉钉配置，请先配置钉钉应用信息'))
        return config
    
    def action_sync_departments(self):
        """同步部门"""
        self.ensure_one()
        return self.env['dingtalk.department'].sync_from_dingtalk()
    
    def action_sync_employees(self):
        """同步员工"""
        self.ensure_one()
        return self.env['dingtalk.employee'].sync_from_dingtalk()

